package org.yxj.lib_downfile.down;

import org.yxj.lib_downfile.LogUtil;
import org.yxj.lib_downfile.bean.DownFileBean;
import org.yxj.lib_downfile.i.DownFileProgressListener;
import org.yxj.lib_downfile.i.ResultListener;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.util.concurrent.TimeUnit;
import okhttp3.Call;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

/**
 * 下载任务
 *
 * @author on 2022/8/26
 */
public class DownFileTask extends Thread implements Runnable {

    /**
     *
     */
    private Call call;
    /**
     * 断点开始下载位置
     */
    private long start = 0;


    private DownFileBean downFileBean ;


    public DownFileTask(DownFileBean downFileBean) {
        this.downFileBean = downFileBean ;
    }




    @Override
    public void run() {
        LogUtil.LOG_V("[DownFileTask]->run()");
        downLoad();
    }


    /**
     * 正在下载
     */
    private boolean isRunning ;


    public boolean isRunning() {
        return isRunning;
    }



    /**
     * 是否已经存在  并且已经下载完成
     * @return
     */
    public void isHaveFile(final ResultListener<Boolean> resultListener){
        if (resultListener!=null){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    File file = new File(downFileBean.filePath);
                    try {
                        RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rwd");
                        if (file.exists()) { //如果当前文件夹存在
                            long read = randomAccessFile.length();//获取已经下载文件的大小
                            start = read;
                        }
                        long total = fileTotalLength();
                        if (start == total) {
                            resultListener.onResult(true);
                        }else {
                            resultListener.onResult(false);
                        }
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                        resultListener.onResult(false);
                    } catch (IOException e) {
                        e.printStackTrace();
                        resultListener.onResult(false);
                    }
                }
            }).start();
        }
    }



    /**
     * 下载
     *
     * @throws IOException
     */
    public void downLoad() {
        isRunning = true ;
        InputStream inputStream = null;
        RandomAccessFile randomAccessFile = null;

        try {
            File file = new File(downFileBean.filePath);
            randomAccessFile = new RandomAccessFile(file, "rwd");
            if (file.exists()) { //如果当前文件夹存在
                long read = randomAccessFile.length();//获取已经下载文件的大小
                start = read;
            }

            long total = fileTotalLength();

//            if (start == total) {
//                isRunning = false ;
//                if (downFileProgressListener!=null){
//                    downFileProgressListener.onHaveDownloaded(file);
//                }
//                return;
//            }


            LogUtil.LOG_V("[DownFileTask]-> 开始下载位置 start=" + start);

            Request request = new Request.Builder()
                    .header("RANGE", "bytes=" + start + "-")
//                    .header("RANGE", "bytes=" + startIndex + "-" + total)
                    .url(downFileBean.fileUrl)
                    .build();


            OkHttpClient client = new OkHttpClient.Builder()
                    .connectTimeout(50, TimeUnit.SECONDS)
                    .readTimeout(50, TimeUnit.SECONDS)
                    .addInterceptor(new MyInterceptor())
                    .build();

            call = client.newCall(request);

            Response response = call.execute();

            if (downFileProgressListener!=null){
                downFileProgressListener.onPending(this,start,total);
            }

            if (response != null && response.body() != null && response.isSuccessful()) {//206表示服务器支持断点续传

                inputStream = response.body().byteStream();
                //移动到开始下载得位置
                randomAccessFile.seek(start);

                byte[] blocks = new byte[(int) (total - start)];

                int len = -1;
                while ((len = inputStream.read(blocks)) > 0) {
                    randomAccessFile.write(blocks, 0, len);
                }
                randomAccessFile.close();
                inputStream.close();
            }

            if (downFileProgressListener!=null){
                downFileProgressListener.onComplete(this,downFileBean);
            }
            LogUtil.LOG_V("[DownFileTask]-> 下载成功 total=" + total);
        } catch (Exception e) {
            e.printStackTrace();
            LogUtil.LOG_V("[DownFileTask]-> 下载失败 = " + e.getMessage());
            if (downFileProgressListener!=null){
                downFileProgressListener.onFail(this,e.getMessage());
            }
        }
        isRunning = false ;
    }


    /**
     * 取消下载
     */
    public void cancel(){
        if (call!=null){
            call.cancel();
            isRunning = false ;
            if (downFileProgressListener!=null){
                downFileProgressListener.cancel(this);
            }
        }
    }


    /**
     * 获取文件总长度
     *
     * @return
     */
    private long fileTotalLength() throws IOException {

        long length = 0;

        OkHttpClient client = new OkHttpClient.Builder().build();

        Request request = new Request.Builder()
                .url(downFileBean.fileUrl)
                .build();

        Call call = client.newCall(request);

        Response response = call.execute();

        if (response != null && response.body() != null && response.isSuccessful()) {
            length = response.body().contentLength();
        } else {
            length = -1;
        }

        LogUtil.LOG_V("[DownFileTask]->fileTotalLength = " + length);

        return length;
    }



    /**
     * 拦截器，用上进度
     * <p>
     * ProgressResponseBody
     */
    private class MyInterceptor implements Interceptor {

        @Override
        public Response intercept(Chain chain) throws IOException {
            Response originalResponse = chain.proceed(chain.request());
            return originalResponse.newBuilder()
                    .body(new ProgressResponseBody(originalResponse.body(), new DownFileProgressListener() {
                        @Override
                        public void onProgress(DownFileBean bean, long progress, long total) {
                            if (downFileProgressListener != null)
                                downFileProgressListener.onProgress(downFileBean, progress+start, total+start);
                        }
                    })).build();
        }
    }


    private DownFileProgressListener downFileProgressListener;


    public DownFileTask setDownFileProgressListener(DownFileProgressListener downFileProgressListener) {
        this.downFileProgressListener = downFileProgressListener;
        return DownFileTask.this;
    }
}
